home *** CD-ROM | disk | FTP | other *** search
- #include <dos.h>
- #include <wgt4.h>
- #include <stdlib.h>
- #include <conio.h>
-
- /* WGT Tutorial #4
- Example Program 2.
-
- This example shows the easiest method of animation. It requires two
- 320x200 screens. The first contains the background image which never
- changes. The second is a work screen, where the sprites will be
- drawn.
-
- The animation loop is very simple. First, copy the background screen
- to the work screen. This erases the previous sprites in a brute force
- method. All the sprites are drawn on the work screen with an xray copy.
- The work screen is copied to the visual screen, and the this process
- is repeated. */
-
- block sprite_images[30]; /* Holds the images for our sprites */
- color pal[256]; /* The palette */
-
- block backgroundscreen; /* Holds the background image */
- block workscreen; /* Holds work screen */
-
- #define NUM_SPRITES 10 /* Maximum number of sprites */
-
- #define SPEED 4 /* Speed and direction of the sprites.
- Negative speeds mean up and left. */
-
-
- /* Our sprite structure */
- typedef struct
- {
- int x, y; /* Coordinate on the screen */
- int num; /* Index into the sprite_image array of blocks */
- int dx, dy; /* speed in the x and y direction */
- int width, height; /* Width and height of the sprite's image */
-
- int ox, oy, ox2, oy2;
- } sprite;
-
- int rx, ry, rx2, ry2;
-
- sprite objects[NUM_SPRITES]; /* an array of sprites */
-
-
-
- void load_graphics (void)
- /* Load the sprites and make our background and work screens. */
- {
- int i;
-
- wloadsprites (pal, "anim.spr", sprite_images, 0, 29);
- wsetpalette (0, 255, pal);
-
- backgroundscreen = wloadpcx256 ("lunar.pcx", pal);
- wputblock (0, 0, backgroundscreen, 0);
- workscreen = wnewblock (0, 0, 319, 199);
- }
-
-
- void free_graphics (void)
- /* Frees the sprite images and the screens */
- {
- wfreesprites (sprite_images, 0, 29);
- wfreeblock (workscreen);
- wfreeblock (backgroundscreen);
- }
-
-
- void initialize_sprites (void)
- /* Set up the initial values in the sprite array */
- {
- int i;
- sprite *spriteptr;
-
- spriteptr = objects;
- for (i = 0; i < NUM_SPRITES; i++)
- {
- spriteptr->num = 0;
- /* Image number 0 */
-
- spriteptr->width = wgetblockwidth (sprite_images[spriteptr->num]);
- spriteptr->height = wgetblockheight (sprite_images[spriteptr->num]);
- /* width and height are the size of the image # num */
-
- spriteptr->x = rand () % 320 - spriteptr->width;
- spriteptr->y = rand () % 200 - spriteptr->height;
- /* Pick a random coordinate */
-
- spriteptr->dx = SPEED;
- spriteptr->dy = SPEED;
- /* Moving down and right */
-
- spriteptr->ox = spriteptr->x;
- spriteptr->oy = spriteptr->y;
- spriteptr->ox2 = spriteptr->x + spriteptr->width - 1;
- spriteptr->oy2 = spriteptr->y + spriteptr->height - 1;
-
- spriteptr++; /* Next sprite */
- }
- }
-
-
-
-
- void erase_sprites (void)
- /* Erases each sprite by copying the section from the background screen. */
- {
- int i;
- sprite *spriteptr;
-
- int x, y, x2, y2;
-
-
- wsetscreen (workscreen);
-
- spriteptr = objects;
-
- for (i = 0; i < NUM_SPRITES; i++)
- {
- x = spriteptr->ox; /* Get the old dirty rectangle coordinates */
- y = spriteptr->oy;
- x2 = spriteptr->ox2;
- y2 = spriteptr->oy2;
-
- if (x < 0) /* Clip them, but don't change the original */
- x = 0; /* values, because we need them later */
- else if (x > 319)
- x = 319;
- if (y < 0)
- y = 0;
- else if (y > 199)
- y = 199;
-
- wcopyscreen (x, y, x2, y2, backgroundscreen, x, y, workscreen);
-
- spriteptr++; /* Next sprite */
- }
- }
-
-
- void expand_dirty_rectangle (int sprite_num, int x, int y, int x2, int y2)
- /* Find boundaries of the old and new sprite rectangle */
- {
- sprite *spriteptr;
-
- spriteptr = &objects[sprite_num];
-
- if (x < rx)
- rx = x;
- if (x2 > rx2)
- rx2 = x2;
- if (y < ry)
- ry = y;
- if (y2 > ry2)
- ry2 = y2;
-
-
- if (rx < 0)
- rx = 0;
-
- if (rx2 > 319)
- rx2 = 319;
-
- if (ry < 0)
- ry = 0;
-
- if (ry2 > 199)
- ry2 = 199;
- }
-
-
-
- void draw_and_move_sprites (void)
- /* Moves each sprite based on the speed and direction, and bounces them
- off the side of the screen if needed. It then draws the sprite on the
- work screen. Sprites are drawn from lowest to highest, meaning the
- higher numbered sprites will be above the rest. */
- {
- int i;
- sprite *spriteptr;
-
- wsetscreen (workscreen);
-
- spriteptr = objects;
-
- for (i = 0; i < NUM_SPRITES; i++)
- {
- spriteptr->num++; /* Animate the sprite through images 0-29 */
- if (spriteptr->num > 29)
- spriteptr->num = 0;
-
- /* Since we changed sprites, we need to get the new width and height
- of the image. Only do this when you change spriteptr->num. */
- spriteptr->width = wgetblockwidth (sprite_images[spriteptr->num]);
- spriteptr->height = wgetblockheight (sprite_images[spriteptr->num]);
-
- spriteptr->x += spriteptr->dx;
- spriteptr->y += spriteptr->dy;
- /* Add the speed/direction to the current coordinate */
-
- if (spriteptr->x > 319 - spriteptr->width)
- spriteptr->dx = -SPEED;
- else if (spriteptr->x < 0)
- spriteptr->dx = SPEED;
- /* Change the direction horizontally if needed */
-
- if (spriteptr->y > 199 - spriteptr->height)
- spriteptr->dy = -SPEED;
- else if (spriteptr->y < 0)
- spriteptr->dy = SPEED;
- /* Change the direction vertically if needed */
-
- wputblock (spriteptr->x, spriteptr->y, sprite_images[spriteptr->num], 1);
- /* Draw the sprite with xray copy */
-
- spriteptr++; /* Next sprite */
- }
- }
-
-
- void copy_sprites (void)
- {
- int i;
- sprite *spriteptr;
- int x, y, x2, y2;
-
- spriteptr = objects;
- for (i = 0; i < NUM_SPRITES; i++)
- {
- /* Store these values because they are used more than once */
- x = spriteptr->x;
- y = spriteptr->y;
- x2 = spriteptr->x + spriteptr->width - 1;
- y2 = spriteptr->y + spriteptr->height - 1;
-
- /* Set the dirty rectangle to the current position of the sprite */
- rx = x;
- ry = y;
- rx2 = x2;
- ry2 = y2;
-
- expand_dirty_rectangle (i, spriteptr->ox, spriteptr->oy,
- spriteptr->ox2, spriteptr->oy2);
-
- wcopyscreen (rx, ry, rx2, ry2, workscreen, rx, ry, NULL);
-
- spriteptr->ox = x;
- spriteptr->oy = y;
- spriteptr->ox2 = x2;
- spriteptr->oy2 = y2;
-
- spriteptr++;
-
- }
- }
-
-
-
- void main (void)
- {
- vga256 ();
-
- load_graphics ();
-
- initialize_sprites ();
-
- do {
-
- erase_sprites ();
- /* Erase the previous frame from the work screen */
-
- draw_and_move_sprites ();
- /* Draw the sprites overtop the work screen */
-
- //wretrace ();
- copy_sprites ();
-
- } while (!kbhit ());
-
-
- free_graphics ();
- wsetmode (3);
- }
-